﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Net;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Animation;
using System.Windows.Shapes;

using System.Collections.ObjectModel;
using System.ServiceModel;
using System.Windows;
using System.Windows.Browser;
using System.Windows.Input;
using Microsoft.Maps.MapControl;
using Microsoft.Maps.MapControl.Core;

namespace WAPA.SilverlightClient
{
    public partial class MainPage : UserControl
    {
        public MainPage()
        {
            InitializeComponent();
        }
             private int geocodesInProgress;
        private PlatformServices.GeocodeServiceClient geocodeClient;

        

        private PlatformServices.GeocodeServiceClient GeocodeClient
        {
            get
            {
                if (null == geocodeClient)
                {
                    //Handle http/https; OutOfBrowser is currently supported on the MapControl only for http pages
                    bool httpsUriScheme = !Application.Current.IsRunningOutOfBrowser && HtmlPage.Document.DocumentUri.Scheme.Equals(Uri.UriSchemeHttps);
                    BasicHttpBinding binding = httpsUriScheme ? new BasicHttpBinding(BasicHttpSecurityMode.Transport) : new BasicHttpBinding(BasicHttpSecurityMode.None);
                    UriBuilder serviceUri = new UriBuilder("http://dev.virtualearth.net/webservices/v1/GeocodeService/GeocodeService.svc");
                    if (httpsUriScheme)
                    {
                        //For https, change the UriSceheme to https and change it to use the default https port.
                        serviceUri.Scheme = Uri.UriSchemeHttps;
                        serviceUri.Port = -1; 
                    }

                    //Create the Service Client
                    geocodeClient = new PlatformServices.GeocodeServiceClient(binding, new EndpointAddress(serviceUri.Uri));
                    geocodeClient.GeocodeCompleted += new EventHandler<PlatformServices.GeocodeCompletedEventArgs>(client_GeocodeCompleted);
                }
                return geocodeClient;
            }
        }

        private GeocodeLayer geocodeLayer;
        private GeocodeLayer GeocodeLayer
        {
            get
            {
                if (null == geocodeLayer)
                {
                    geocodeLayer = new GeocodeLayer(cloudMap);
                }
                return geocodeLayer;
            }
        }

        private void GeocodeAddress(string address)
        {
            PlatformServices.GeocodeRequest request = new PlatformServices.GeocodeRequest();
            request.Culture = cloudMap.Culture;
            request.Query = address;
            // Don't raise exceptions.
            request.ExecutionOptions = new PlatformServices.ExecutionOptions();
            request.ExecutionOptions.SuppressFaults = true;

            // Only accept results with high confidence.
            request.Options = new PlatformServices.GeocodeOptions();
            // Using ObservableCollection since this is the default for Silverlight proxy generation.
            request.Options.Filters = new ObservableCollection<PlatformServices.FilterBase>();
            PlatformServices.ConfidenceFilter filter = new PlatformServices.ConfidenceFilter();
            filter.MinimumConfidence = PlatformServices.Confidence.High;
            request.Options.Filters.Add(filter);

            Output.Text = "< geocoding " + address + " >";
            geocodesInProgress++;

            cloudMap.CredentialsProvider.GetCredentials(
                (Credentials credentials) =>
                {
                    //Pass in credentials for web services call.
                    //Replace with your own Credentials.
                    request.Credentials = credentials;

                    // Make asynchronous call to fetch the data ... pass state object.
                    GeocodeClient.GeocodeAsync(request, address);
                });
        }

        private void client_GeocodeCompleted(object sender, PlatformServices.GeocodeCompletedEventArgs e)
        {
            // Callback when the geocode is finished.
            string outString;
            geocodesInProgress--;
            try
            {
                if (e.Result.ResponseSummary.StatusCode != PlatformServices.ResponseStatusCode.Success)
                {
                    outString = "error geocoding ... status <" + e.Result.ResponseSummary.StatusCode.ToString() + ">";
                }
                else if (0 == e.Result.Results.Count)
                {
                    outString = "No results";
                }
                else
                {
                    // Only report on first result.
                    outString = e.Result.Results[0].DisplayName;
                    Location loc = GeocodeLayer.AddResult(e.Result.Results[0]);
                    
                    // Zoom the map to the location of the item.
                    //cloudMap.SetView(loc, 18);

                    double markerSize = 25;
                    cloudDataCenterLayer.AddChild(new Ellipse { Tag = outString, Width = markerSize, Height = markerSize, Margin = new Thickness(-1 * markerSize, -1 * markerSize, 0, 0), Fill = new SolidColorBrush { Color = Colors.White } }, loc);

                    cloudDataCenterLayer.AddChild(new CloudShape { }, loc);
                   
                    //dataCenterCloud.Arrange(new Rect(dataCenterCloud.Width, dataCenterCloud.Height, loc.Longitude, loc.Latitude));
                }
            }
            catch
            {
                outString = "Exception raised";
            }

            Output.Text = outString;
        }


        private void GeocodeInput()
        {
            // Geocode whatever is in the textbox.
            string address = Input.Text;
            if (address.Length > 0)
            {
                GeocodeAddress(address);
            }
        }

        private void Button_Click(object sender, RoutedEventArgs e)
        {
            GeocodeInput();
        }

        private void Input_KeyDown(object sender, KeyEventArgs e)
        {
            if (e.Key == Key.Enter)
            {
                GeocodeInput();
            }
        }

        private void Input_GotFocus(object sender, RoutedEventArgs e)
        {
            Input.SelectAll();
        }

        private void cloudMap_MousePan(object sender, MapMouseDragEventArgs e)
        {
            e.Handled = true;
        }

       
    }
}
